package sk.tonyb.library.textprocessor.html;

import java.util.ArrayList;
import java.util.List;

import org.apache.log4j.Logger;

import sk.tonyb.library.collection.ListProcessor;

/** 
 * Class, which contains mathods used for parsing HTML document. 
 * 
 * @author Anton Balucha
 * @since 07.10.2011
 * @last_modified 08.10.2011
 */
public class HtmlParser {

	/** Log4j logger. */
	public static Logger logger = Logger.getLogger(HtmlParser.class);
	
	/** HTML text, which will be parsed. */
	private String text = null;
	
	/** List of parsed links. */
	private List<String> listOfLinksList = null;
	private String[] listOfLinksString = null;

	// HTML tags
	/** LINK_TAG_START = "href=" */
	private String LINK_TAG_START = "href=\"";
	/** LINK_TAG_END = "\"" */
	private String LINK_TAG_END = "\"";
	/** HTML_TAG_OPEN = "<" */
	private String HTML_TAG_OPEN = "<";
	/** HTML_TAG_CLOSE = ">" */
	private String HTML_TAG_CLOSE = ">";
	/** SPACE = " " */
	private String SPACE = " ";
	
	/** 
	 * Constructor. <br>
	 * 
	 * @param text - text, which will be parsed. <br>
	 * @throws NullPointerException - if enterd text is null or empty. <br>
	 */
	public HtmlParser(String text) throws NullPointerException {
		
		if(text == null || text.trim().isEmpty()) {
			throw new NullPointerException("Entered value text is null or empty.");
		}
		
		this.text = text;
		this.parse();
	}

	/** 
	 * Method, which return text, which will be parsed. <br>
	 * 
	 * @return text - text, which will be parsed. <br>
	 */
	public synchronized String getText() {
		return this.text;
	}
	
	/** 
	 * Method, which return list of links as List. <br>
	 * 
	 * @return listOfLinksList - list of parsed links as List. <br>
	 */
	public synchronized List<String> getListOfLinks1() {
		return this.listOfLinksList;
	}

	/** 
	 * Method, which return list of links as String[]. <br>
	 * 
	 * @return listOfLinksString - list of parsed links as String[]. <br>
	 */
	public synchronized String[] getListOfLinks2() {
		return this.listOfLinksString;
	}
	
	/** Method, which starts all implemented parsers. */
	private synchronized void parse() {
		this.parseLinks();
	}
	
	/** Method, which provides parsing of links. Method parse link only when are in proper HTML notation in quotes. */
	private synchronized void parseLinks() {
		
		String link = null;
		int indexLinkTagStart = 0;
		int indexLinkTagEnd = 0;
		int indexHtmlTagEnd = 0;
		
		try {
			
			this.listOfLinksList = new ArrayList<String>();
			indexLinkTagStart = this.text.indexOf(this.LINK_TAG_START);
			indexLinkTagEnd = this.text.indexOf(this.LINK_TAG_END, indexLinkTagStart + this.LINK_TAG_START.length()) + this.LINK_TAG_END.length();
			indexHtmlTagEnd = this.text.indexOf(this.HTML_TAG_CLOSE, indexLinkTagStart + this.LINK_TAG_START.length()) + this.HTML_TAG_CLOSE.length();
			
			while(indexLinkTagStart > -1 && indexLinkTagEnd > -1) {
				
				if(indexLinkTagEnd > indexHtmlTagEnd) {
					link = this.text.substring(indexLinkTagStart + this.LINK_TAG_START.length(), indexHtmlTagEnd - 1);
					indexLinkTagEnd = indexHtmlTagEnd;
				}
				
				else {
					link = this.text.substring(indexLinkTagStart + this.LINK_TAG_START.length(), indexLinkTagEnd - 1);
				}
				
				link = link.trim();
				
				this.listOfLinksList.add(link);
				
				indexLinkTagStart = this.text.indexOf(this.LINK_TAG_START, indexLinkTagEnd + 1);
				indexLinkTagEnd = this.text.indexOf(this.LINK_TAG_END, indexLinkTagStart + this.LINK_TAG_START.length()) + this.LINK_TAG_END.length();
				indexHtmlTagEnd = this.text.indexOf(this.HTML_TAG_CLOSE, indexLinkTagStart + this.LINK_TAG_START.length()) + this.HTML_TAG_CLOSE.length();
			}
			
			this.listOfLinksString = new ListProcessor().convert(this.listOfLinksList);
		}
		
		catch(Exception e) {
			logger.error("[indexStart = " + indexLinkTagStart + "] [indexEnd = " + indexLinkTagEnd + "] [indexHtmlTagEnd = " + indexHtmlTagEnd + "]");
			logger.error("Exception", e);
		}
	}
}
